package com.x.compute.core.handle.column;

import cn.hutool.core.util.StrUtil;
import com.x.compute.core.annotation.ComputeTable;
import com.x.compute.core.annotation.ComputeVar;
import com.x.compute.core.entity.ComputeColumn;
import com.x.compute.core.entity.ComputeExpression;
import com.x.compute.core.entity.ComputeParam;
import com.x.compute.core.entity.Variable;
import com.x.compute.common.util.ComputeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 列变量处理器
 *
 * @author xuxin
 */
@Slf4j
public abstract class ColumnVarHandle {

    /**
     * 获取表格id
     * @return
     */
    public abstract String getTableId();

    /**
     * 获取数据源
     * @param formId 表单id
     * @param referenceValueMap 引用变量及值的键值对
     * @return
     */
    public abstract List<? extends ComputeColumn> dataSource(Long formId, Map<String, Object> referenceValueMap);

    /**
     * 注入变量值集
     * @param formId 表单id
     * @param columnVariables 列变量集
     * @param referenceValueMap 引用变量及值的键值对
     */
    public void injectReferenceValue(Long formId, List<Variable> columnVariables, Map<String, Object> referenceValueMap){
        List<? extends ComputeColumn> dataSet = dataSource(formId, referenceValueMap);
        if (CollectionUtils.isEmpty(dataSet)){
            return;
        }
        dataSet.forEach(data ->{
            Long id = data.getId();
            Class clazz = data.getClass();
            for (Variable column : columnVariables) {
                String variable = ComputeUtils.getColumnVarFullName(column.getTableId(), column.getName());
                Map<String, Object> valueMap = (Map<String, Object>) referenceValueMap.getOrDefault(variable, new HashMap<String, Object>());
                try {
                    Field field = clazz.getDeclaredField(column.getName());
                    field.setAccessible(true);
                    Object value = field.get(data);
                    valueMap.put(id.toString(), value);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        });
    }

    /**
     * 变量值映射
     * @param businessId 业务id
     * @param column 计算列
     * @param varValueMap 变量值集
     */
    public void valueReflection(Long businessId, ComputeColumn column, Map<String, String> varValueMap){
        column.setId(businessId);
        Class clazz = column.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            try {
                String fieldName = field.getName();
                if (fieldName.equals("id")){
                    continue;
                }
                field.setAccessible(true);
                Object fieldValue = varValueMap.get(ComputeUtils.getVarFullName(fieldName, businessId.toString()));
                field.set(column, fieldValue);
            }catch (IllegalAccessException e){

            }
        }
    }
}
